/**     
 * @Title: RedisConfig.java   
 * @Package me.xxy.mq   
 * @Description: TODO
 * @author weiwei 
 * @date 2018年5月31日 下午3:52:28   
 * @version V1.0     
 */
package me.xxy.mq;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisPubSub;

/**
 * @ClassName: RedisConfig
 * @Description: TODO
 * @author weiwei
 * @date 2018年5月31日 下午3:52:28
 * 
 */
public class RedisConfig implements InitializingBean {

	private static final Log LOG = LogFactory.getLog(RedisConfig.class);

	/** REDIS连接池 **/
	private volatile JedisPool jedisPool;

	/**
	 * 最大连接数，如果赋值为-1，则表示不限制；如果pool已经分配了maxActive个JEDIS实例，则此时pool的状态为exhausted(耗尽
	 * )。
	 **/
	private Integer maxTotal;

	/** 控制一个pool最多有多少个状态为idle(空闲的)的JEDIS实例 **/
	private Integer maxIdle;

	private Integer minIdle;

	/** 最大的等待时间，如果超过等待时间，则直接抛出JedisConnectionException； **/
	@SuppressWarnings("unused")
	private Integer holed;

	/** redis服务端口 **/
	private Integer port;

	/** edis服务地址 **/
	private String host;

	/** redis连接超时时间 **/
	private Integer timeout;

	/** redis连接密码 **/
	private String password;

	/** 数据库 **/
	private Integer database;

	@SuppressWarnings("unused")
	private String keyPrefix;

	@Override
	public void afterPropertiesSet() throws Exception {
		JedisPoolConfig config = new JedisPoolConfig();
		config.setMaxTotal(maxTotal);
		config.setMaxIdle(maxIdle);
		config.setMinIdle(minIdle);
		jedisPool = new JedisPool(config, host, port, timeout, password, database);
	}

	/**
	 * @Title: getConnent
	 * @Description: 从连接池获得一个redis连接
	 * @Reutrn Jedis
	 */
	public Jedis getConnent() {
		Jedis jedis = jedisPool.getResource();
		return jedis;
	}

	/**
	 * @Title: close
	 * @Description: 关闭当前连接实例，将连接返回连接池
	 * @param jedis
	 * @Reutrn void
	 */
	private void close(Jedis jedis) {
		try {
			if (jedis != null) {
				jedis.close();
			}
		} catch (Exception e) {
			LOG.error("close jedis failed!", e);
		}
	}

	public Long publish(String channel, String message) {
		Jedis jedis = null;
		try {
			jedis = getConnent();
			Long result = jedis.publish(channel, message);
			return result;
		} catch (Exception e) {
			LOG.error("redis get data failed!", e);
			return -1L;
		} finally {
			close(jedis);
		}
	}

	public List<String> pubsubChannels(String pattern) {
		Jedis jedis = null;
		try {
			jedis = getConnent();
			List<String> result = jedis.pubsubChannels(pattern);
			return result;
		} catch (Exception e) {
			LOG.error("redis get data failed!", e);
			return null;
		} finally {
			close(jedis);
		}
	}

	public void subscribed(JedisPubSub jedisPubSub, String... channels) {
		Jedis jedis = null;
		try {
			jedis = getConnent();
			jedis.subscribe(jedisPubSub, channels);
		} catch (Exception e) {
			LOG.error("redis get data failed!", e);
		} finally {
			close(jedis);
		}
	}

	/**
	 * @param jedisPool
	 *            the jedisPool to set
	 */
	public void setJedisPool(JedisPool jedisPool) {
		this.jedisPool = jedisPool;
	}

	/**
	 * @param maxTotal
	 *            the maxTotal to set
	 */
	public void setMaxTotal(Integer maxTotal) {
		this.maxTotal = maxTotal;
	}

	/**
	 * @param maxIdle
	 *            the maxIdle to set
	 */
	public void setMaxIdle(Integer maxIdle) {
		this.maxIdle = maxIdle;
	}

	/**
	 * @param minIdle
	 *            the minIdle to set
	 */
	public void setMinIdle(Integer minIdle) {
		this.minIdle = minIdle;
	}

	/**
	 * @param holed
	 *            the holed to set
	 */
	public void setHoled(Integer holed) {
		this.holed = holed;
	}

	/**
	 * @param port
	 *            the port to set
	 */
	public void setPort(Integer port) {
		this.port = port;
	}

	/**
	 * @param host
	 *            the host to set
	 */
	public void setHost(String host) {
		this.host = host;
	}

	/**
	 * @param timeout
	 *            the timeout to set
	 */
	public void setTimeout(Integer timeout) {
		this.timeout = timeout;
	}

	/**
	 * @param password
	 *            the password to set
	 */
	public void setPassword(String password) {
		this.password = password;
	}

	/**
	 * @param database
	 *            the database to set
	 */
	public void setDatabase(Integer database) {
		this.database = database;
	}

	/**
	 * @param keyPrefix
	 *            the keyPrefix to set
	 */
	public void setKeyPrefix(String keyPrefix) {
		this.keyPrefix = keyPrefix;
	}
}
